package src.model.gameWorld;

import src.model.gameObject.*;
import src.model.gameObject.ability.*;
import src.model.gameWorld.LookupTable;

/**
 * <b>Overview</b><br>
 * <p>To ensure that GameObjects are constructed in a uniform and correct
 * manner, the actual construciton of a GameObject takes place inside a 
 * factory.</p>
 * <br><br>
 * <b>Responsibilites</b><br>
 * <p>Construt and initilize abilites for GameObjects</p>
 * <br><br>
 * <b>Collaborators</b>
 * <br><br>
 * <ul>
 * <li>GameObject - Client</li>
 * <li>PlayerGameObject - Client</li>
 * <li>Position - Subcontractor</li>
 * <li>ActualMap - Subcontractor</li>
 * <li>LookupTable - Subcontractor</li>
 * </ul>
 * <b>Implementor</b> - Brent<br>
 * <b>Tester</b> - Bruce<br>
 * 
 * @author Brent
 *
 */
public class GameObjectFactory{

	private ActualMap actualMap;
	private LookupTable lookupTable;

	/**
	 * Constructs a new Factory, giving it everything it needs to build
	 * GameObjects.
	 * 
	 * @param actualMap - the current ActualMap
	 * @param globalLookupTable - the global LookupTable
	 */
	public GameObjectFactory(ActualMap actualMap, LookupTable globalLookupTable){

		this.actualMap = actualMap;
		this.lookupTable = globalLookupTable;

	}

	/**
	 * Used to construct a GameObject
	 * 
	 * @param got - the type
	 * @param gost - the subtype
	 * @param pos - the position
	 * @return the newly created GameObject
	 */
	public GameObject newGO(GameObjectType got, GameObjectSubtype gost, Position pos)
	{
		GameObject go = new GameObject(got, gost);
		
		actualMap.placeObject(go, pos);
		
		if(got == GameObjectType.TERRAIN && gost == GameObjectSubtype.WATER)
		{
			go.addAbility(AbilityFactory.constructAbility(
					go,
					AbilityType.PASSABLE,
					lookupTable,
					actualMap));
			
		}
		
		return go;
	}

	/**
	 * Used to construct a PlayerGameObject
	 * 
	 * @param got - the type
	 * @param gost - the subtype
	 * @param pos - the position
	 * @param p - the player the object will belong to
	 * @return the newly created PlayerGameObject
	 */
	public PlayerGameObject newPGO(GameObjectType got, GameObjectSubtype gost, Position pos, Player p){
		PlayerGameObject pgo = new PlayerGameObject(got, gost, p);
	
		actualMap.placeObject(pgo, pos);
		
		
		
		if (got == GameObjectType.UNIT && gost == GameObjectSubtype.CORSAIR)
		{
			pgo.addAbility(AbilityFactory.constructAbility(
					pgo, 
					AbilityType.VIEW, 
					p.getLookupTable(), 
					actualMap));
			
			pgo.addActiveAbility(ActiveAbilityFactory.constructActiveAbility(
					pgo, 
					AbilityType.MOVE,
					p.getLookupTable(),
					actualMap));			
		}
		
		p.newUnit(pgo, pos);
	
		return pgo;
	}	
}
